import React, { useRef, useEffect, useState, useImperativeHandle } from "react";
import G6 from '@antv/g6';
import { formatRelationData, formatResourceData, arrayTreeAddLevel} from "./config/utils";
import {CmdbContent, CmdbHeader, } from "@/components";
import { message, } from "antd"
import registerEdge from './config/register-edge';
import registerNode from './config/register-node';
import { defaultNodeConfig, defaultEdgeConfig, defaultLayout, defaultTooltip } from "./config/default";
import request from "@/utils/request";
import cmdbres from "@/data/cmdbres";
import './index.less';

const BusinessEcsTopology = ({ biz, moduleList, bizModuleList, BizModelCodes }) => {
    const GRAPH_ID = "model-graph-container";
    const domRef = useRef(null);
    const graphRef = useRef(null);
    let graph = graphRef.current;
    const [data, setData] = useState();
    const [loading, setLoading] = useState(false);
    const [associateType, setAssociateType] = useState();

    useEffect(() => {
        if(!BizModelCodes.length || (BizModelCodes.length && bizModuleList.length)) {
            fetchAssociateType();
            fetchData();
        }
    }, [biz, bizModuleList]);

    const queryBizPool = async () => {
        try {
            const res = await request({
                ...cmdbres.queryBizPool(biz.cm_unid),
                params: {},
            });
            let obj = {};
            if(res && res.data) {
                obj = res.data;
                obj.instanceId = obj.setId;
                obj.instanceName = obj.setName;
                obj.serviceInstances?.map(item => {
                    item.instanceId = item.serviceId;
                    item.instanceName = item.serviceName;
                })
                obj.children = obj.serviceInstances;
            }
            return obj;
        } catch (error) {
            console.log(error);
        } 
    };

    const queryBizTopologyList = async () => {
        try {
            const res = await request({
                ...cmdbres.queryBizTopologyList(biz.cm_unid),
                params: {},
            });
            return res.data;
        } catch (error) {
            console.log(error);
        } 
    };
    

    const fetchData = async () => {
        try {
            const [treeObj, poolData] = await Promise.all([queryBizTopologyList(), queryBizPool()]);
            if(treeObj && poolData) {
                if(JSON.stringify(poolData) != "{}") {
                    treeObj.children.unshift(poolData);
                }
                let resData = arrayTreeAddLevel([treeObj]);
                setData(resData?.[0]);
            }
        } catch (error) {
            console.log(error);
        }
    };

    const fetchAssociateType = async () => {
        try {
            let res = await request({
                ...cmdbres.queryAssociateType,
                data:{
                    pageSize: 9999,
                    pageNumber: 1,
                }
            });
            if (res && res.code == 200) {
                let obj = {}
                if(res.data) {
                    res.data.map(item=> obj[item.associateTypeCode] = item.name);
                }
                setAssociateType(obj)
            }else {
                setAssociateType({})
            }
        } catch (error) {
            console.log(error);
        }
    };

    useEffect(() => {
        if(!(data && associateType)) return;
        fetchLayout(true);
        return () => {
            if(graph) {
                graph.destroy();
            }
        };
    },[data, associateType]);
    const createGraphic = async() => {
        // 注册自定义节点
        registerEdge(G6);
        // 注册自定义边
        registerNode(G6);

        const container = document.getElementById(GRAPH_ID);
        const tree = new G6.TreeGraph({
            container: domRef.current,
            width: container.offsetWidth,
            height: container.offsetHeight,
            defaultNode: defaultNodeConfig,
            defaultEdge: defaultEdgeConfig,
            layout: defaultLayout,
            animate: true,
            modes: {
                default: [
                    {
                        type: 'collapse-expand',
                        trigger: 'click',
                    },
                    'drag-canvas',
                    'zoom-canvas',
                ],
            },
            plugins: [
                new G6.Grid(),
                new G6.Minimap({
                    size: [200, 150],
                }),
                defaultTooltip,
            ],
            fitView: true,
            fitViewPadding:20,
            minZoom: 0.7,
            maxZoom: 1,
        });

        graphRef.current = tree;
        return tree;
    };
    const fetchLayout = async() => {
        createGraphic().then(res=> {
            graph = res;
            graph.read({ ...data });
            // 关闭局部渲染解决缩放或者拖拽引起的残影问题（关闭会影响性能，临时解决办法）
            graph.get('canvas').set('localRefresh', false);
            bindEvents();
        });

    }

    const queryRelationData = async (id, queryModuleId, level) => {
        if(!id) {
            console.log("未获取到cm_unid:" + info);
            return;
        }
        setLoading(true);
        try {
            let res = await request({
                ...cmdbres.queryRelationData,
                params: {
                    id: id,
                    queryModuleId,
                    pageSize: 10000,
                    pageNumber: 1,
                },
            });
            setLoading(false);
            if(res && res.data) {
                if(!res.data.length) {
                    message.warning("暂无数据！");
                    return [];
                }
                return formatRelationData(id, res.data, associateType, level);
            }
            return [];
        } catch (error) {
            console.log(error);
        }
    };

    const queryResourceData = async (serviceId, level) => {
        try {
            const cmModuleId = bizModuleList.map(item => item.cmModuleId);
            const res = await request({
                ...cmdbres.queryBizServers,
                data: {
                    serviceId,
                    cmModuleId,
                    sort:{
                        cm_create_time:"DESC"
                    },
                },
            });
            if (res && res.data) {
                if(!res.data.length) {
                    message.warning("暂无数据！");
                    return [];
                }
                return formatResourceData(res.data, level, moduleList);
            }
            return [];
        } catch (error) {
            console.log(error);
        } 
    }

    const bindEvents = () => {
        graph.on('node:dblclick', (e)=> {
            const item = e.item;
            if(!bizModuleList?.length) {
                message.warning("未获取到要查询的模型");
                return;
            }
            const model = item.getModel();
            if((model.isBiz && model.moduleCode != "service") || item.hasState("isLoadingChildren") || model.children?.length > 0) return false;
            
            const lastPoint = graph.getCanvasByPoint(0, 0);
            graph.setItemState(item, 'isLoadingChildren', true);
            let resData = null;
            if(model.isBiz && model.moduleCode == "service") {// 服务模块查询的是业务关联的资源
                resData = queryResourceData(model.key, model.level);
            } else {// 非业务模块查询的是关联资源
                let queryModuleId = undefined;
                // if(!BizModelCodes.includes(model.moduleCode)) {
                    const edges = item.getEdges();
                    edges.map(ed => {
                        const _cmModuleId = ed.getSource().getModel().cmModuleId;
                        if(_cmModuleId != model.cmModuleId) {
                            queryModuleId = _cmModuleId;
                        }
                    })
                // }
                resData = queryRelationData(model.key, queryModuleId, model.level);
            }
            resData.then((res)=>{
                if(!(res && res.length)){
                    graph.clearItemStates(item, 'isLoadingChildren');
                    return false;
                }
                if(item.hasState("isLoadingChildren") && res) {
                    if(!model.children) {
                        // model.children = res;
                        model.childrenCount = res.length;
                        graph.updateChildren(res, model.id);
                        graph.updateItem(item, model);
                        graph.clearItemStates(item, 'isLoadingChildren');
                        item.toFront();
                        const newPoint = graph.getCanvasByPoint(0, 0);
                        graph.translate(lastPoint.x - newPoint.x, lastPoint.y - newPoint.y);
                    }
                }
            });
        })
    }

    return (  
        <>
            <CmdbContent>
                <div style={{ width: '100%', height: 710, position: 'relative' }}>
                    <div ref={domRef} id={GRAPH_ID} style={{ width: '100%', height: '100%'}} ></div>
                </div>
            </CmdbContent>
        </>
    )
}
export default BusinessEcsTopology;



  

